use std::path::{Path, PathBuf};
use std::collections::HashMap;
use anyhow::Result;
use log::{debug, info, warn};

use crate::errors::ConversionError;

/// 表示解决方案中的项目
#[derive(Debug, Clone)]
pub struct SolutionProject {    pub name: String,
    pub guid: String,
    pub _path: PathBuf,  // 保留以备将来使用
    pub dependencies: Vec<String>,
}

/// 表示一个Visual Studio解决方案
#[derive(Debug, Clone)]
pub struct Solution {
    pub solution_name: String,
    pub projects: Vec<SolutionProject>,
}

/// 解析Visual Studio解决方案文件
pub fn parse_solution(solution_path: &Path) -> Result<Solution> {
    info!("解析解决方案文件: {}", solution_path.display());
    
    if !solution_path.exists() {
        return Err(ConversionError::SolutionNotFound(solution_path.to_path_buf()).into());
    }
    
    // 读取解决方案文件内容
    let solution_content = std::fs::read_to_string(solution_path)?;
    let solution_dir = solution_path.parent().unwrap_or(Path::new("."));
    
    // 解析解决方案名称
    let solution_name = solution_path.file_stem().unwrap_or_default().to_string_lossy().to_string();
    
    // 用于解析项目条目的正则表达式
    // 格式: Project("{项目类型GUID}") = "项目名称", "项目文件相对路径", "{项目GUID}"
    let project_regex = regex::Regex::new(r#"Project\("\{([^}]*)\}"\) = "([^"]*)", "([^"]*)", "\{([^}]*)\}""#).unwrap();
    
    // 用于解析项目依赖关系的正则表达式
    let dependency_section_regex = regex::Regex::new(r"GlobalSection\(ProjectConfigurationPlatforms\)(?s).*?EndGlobalSection").unwrap();
    let dependency_regex = regex::Regex::new(r#"\{([^}]*)\}\.(?:[^=]*) = (?:[\d.]*)"#).unwrap();
    
    let mut projects = Vec::new();
    let mut project_guids = HashMap::new();
    
    // 提取项目
    for cap in project_regex.captures_iter(&solution_content) {
        let project_type = cap[1].to_string();
        let name = cap[2].to_string();
        let relative_path = cap[3].to_string();
        let guid = cap[4].to_string();
        
        // 跳过解决方案文件夹和其他非C++项目
        if project_type.to_lowercase() == "2150e333-8fdc-42a3-9474-1a3956d46de8" {
            debug!("跳过解决方案文件夹: {}", name);
            continue;
        }
        
        let project_path = solution_dir.join(relative_path.replace('\\', "/"));
        
        if project_path.exists() {            let project = SolutionProject {
                name: name.clone(),
                guid: guid.clone(),
                _path: project_path.clone(),
                dependencies: Vec::new(),
            };
            
            project_guids.insert(guid, projects.len());
            projects.push(project);
            
            debug!("找到项目: {} 位于 {}", name, project_path.display());
        } else {
            warn!("项目文件未找到: {}", project_path.display());
        }
    }
    
    // 提取项目依赖关系
    if let Some(dep_section) = dependency_section_regex.find(&solution_content) {
        let dep_section_str = &solution_content[dep_section.start()..dep_section.end()];
        
        // 创建项目GUID的映射
        let mut guid_to_index = HashMap::new();
        for (i, project) in projects.iter().enumerate() {
            guid_to_index.insert(project.guid.clone(), i);
        }
        
        // 处理依赖关系
        let mut processed_guids = HashMap::new();
        
        for cap in dependency_regex.captures_iter(dep_section_str) {
            let guid = cap[1].to_string();
            
            // 如果已经处理过这个GUID，跳过
            if processed_guids.contains_key(&guid) {
                continue;
            }
            
            processed_guids.insert(guid.clone(), true);
            
            // 查找具有此GUID的项目
            if let Some(&index) = guid_to_index.get(&guid) {
                // 该项目有依赖项，处理它们
                let pattern = format!(r#"\{{{}\}}\.(?:[^=]*) = \{{([^}}]*)\}}"#, guid);
                let dep_regex = regex::Regex::new(&pattern).unwrap();
                
                for dep_cap in dep_regex.captures_iter(dep_section_str) {
                    let dep_guid = dep_cap[1].to_string();
                    
                    // 通过GUID查找依赖项目
                    if let Some(&dep_index) = guid_to_index.get(&dep_guid) {
                        // 克隆名称以避免多次借用
                        let dep_name = projects[dep_index].name.clone();
                        let project_name = projects[index].name.clone();
                        
                        // 如果尚未添加，则添加依赖项
                        if !projects[index].dependencies.contains(&dep_name) {
                            projects[index].dependencies.push(dep_name.clone());
                            debug!("项目 {} 依赖于 {}", project_name, dep_name);
                        }
                    }
                }
            }
        }
    }
    
    debug!("在解决方案中找到 {} 个项目", projects.len());
      Ok(Solution {
        solution_name,
        projects,
    })
} 